import { Injectable } from '@angular/core';
import {Actions, ofType, Effect} from '@ngrx/effects';
import { Observable, of , pipe} from 'rxjs';
import { Router} from '@angular/router';
import * as actions from '../actions/task-list.action';
import {
    LoadAction,
    AddAction,
    UpdateAction,
    DeleteAction,
    LoadSuccessAction,
    SwapAction
 } from '../actions/task-list.action';
import * as taskActions from '../actions/task.action';
import { Action, Store , select} from '@ngrx/store';
import * as fromRoot from '../reducers';
import { switchMap, map, catchError , tap, withLatestFrom} from 'rxjs/operators';
import { TaskList } from '../domain';
import { TaskListService } from '../services/task-list.service';
@Injectable()
export class TaskListEffects {
    @Effect()
    loadTaskLists$:Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.LOAD),
        map((a: LoadAction) => a.payload),
        switchMap(projectId => this.taskListService.getTaskLists(projectId).pipe(
            map(tasklists => new actions.LoadSuccessAction(tasklists)),
            catchError(err => of(new actions.LoadFailAction(JSON.stringify(err)))
            ))),
    );

    @Effect()
    addTaskLists$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.ADD),
        map((a: AddAction) => a.payload),
        switchMap((taskList) => this.taskListService.add(taskList).pipe(
            map(tl => new actions.AddSuccessAction(tl)),
            catchError(err => of(new actions.AddFailAction(err)))
        ))
    );
    @Effect()
    updateTaskLists$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.UPDATE),
        map((a: UpdateAction) => a.payload),
        switchMap(taskList => this.taskListService.update(taskList).pipe(
            map(tl => new actions.UpdateSuccessAction(tl)),
            catchError(err => of(new actions.UpdateFailAction(err)))
        ))
    );
    @Effect()
    delTaskLists$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.DELETE),
        map((a: DeleteAction) => a.payload),
        switchMap(taskList => this.taskListService.del(taskList).pipe(
            map(tl => new actions.DeleteSuccessAction(tl)),
            catchError(err =>  of(new actions.DeleteFailAction(err)))
        ))
    );
    @Effect()
    swap$: Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.SWAP),
        map((a: SwapAction) => a.payload),
        switchMap(({src, target}) => this.taskListService.swapOrder(src, target).pipe(
            map(taskLists => new actions.SwapSuccessAction(taskLists)),
            catchError(err => of(new actions.SwapFailAction(err)))
        )),
    );
    @Effect()
    loadTasksInLists$:Observable<Action> = this.actions$.pipe(
        ofType(actions.ActionTypes.LOAD_SUCCESS),
        map((a: LoadSuccessAction) => a.payload),
        map(lists => new taskActions.LoadAction(lists))
    );
    constructor(
        public actions$: Actions,
        public taskListService: TaskListService,
        public store$: Store<fromRoot.State>,
        public router: Router
      ) {}
}
